using AuthService.Domain.Common;
using System.Linq.Expressions;

namespace AuthService.Domain.Repositories;

/// <summary>
/// 通用仓储接口
/// 提供基础的CRUD操作和查询功能
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <typeparam name="TKey">主键类型</typeparam>
public interface IBaseRepository<TEntity, TKey> where TEntity : BaseEntity
{
    #region 基础CRUD操作

    /// <summary>
    /// 根据ID获取实体
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>实体对象</returns>
    Task<TEntity?> GetByIdAsync(TKey id, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取所有实体
    /// </summary>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>实体列表</returns>
    Task<IEnumerable<TEntity>> GetAllAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// 创建实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>创建的实体</returns>
    Task<TEntity> CreateAsync(TEntity entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>更新的实体</returns>
    Task<TEntity> UpdateAsync(TEntity entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除实体（软删除）
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <param name="deletedBy">删除者</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否成功</returns>
    Task<bool> DeleteAsync(TKey id, string? deletedBy = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 物理删除实体
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否成功</returns>
    Task<bool> HardDeleteAsync(TKey id, CancellationToken cancellationToken = default);

    #endregion

    #region 批量操作

    /// <summary>
    /// 批量创建
    /// </summary>
    /// <param name="entities">实体列表</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>创建的实体列表</returns>
    Task<IEnumerable<TEntity>> CreateBatchAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量更新
    /// </summary>
    /// <param name="entities">实体列表</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>更新的实体列表</returns>
    Task<IEnumerable<TEntity>> UpdateBatchAsync(IEnumerable<TEntity> entities, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量删除（软删除）
    /// </summary>
    /// <param name="ids">主键ID列表</param>
    /// <param name="deletedBy">删除者</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>删除的数量</returns>
    Task<int> DeleteBatchAsync(IEnumerable<TKey> ids, string? deletedBy = null, CancellationToken cancellationToken = default);

    #endregion

    #region 查询操作

    /// <summary>
    /// 根据条件查询
    /// </summary>
    /// <param name="whereClause">WHERE条件</param>
    /// <param name="parameters">参数</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>实体列表</returns>
    Task<IEnumerable<TEntity>> FindAsync(string whereClause, object? parameters = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据条件查询单个实体
    /// </summary>
    /// <param name="whereClause">WHERE条件</param>
    /// <param name="parameters">参数</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>实体对象</returns>
    Task<TEntity?> FindFirstAsync(string whereClause, object? parameters = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="pageNumber">页码（从1开始）</param>
    /// <param name="pageSize">每页大小</param>
    /// <param name="whereClause">WHERE条件</param>
    /// <param name="orderBy">排序条件</param>
    /// <param name="parameters">参数</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>分页结果</returns>
    Task<(IEnumerable<TEntity> Items, int TotalCount)> GetPagedAsync(
        int pageNumber = 1,
        int pageSize = 20,
        string? whereClause = null,
        string? orderBy = null,
        object? parameters = null,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 检查实体是否存在
    /// </summary>
    /// <param name="whereClause">WHERE条件</param>
    /// <param name="parameters">参数</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否存在</returns>
    Task<bool> ExistsAsync(string whereClause, object? parameters = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取数量
    /// </summary>
    /// <param name="whereClause">WHERE条件</param>
    /// <param name="parameters">参数</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>数量</returns>
    Task<int> CountAsync(string? whereClause = null, object? parameters = null, CancellationToken cancellationToken = default);

    #endregion

    #region 事务操作

    /// <summary>
    /// 在事务中执行操作
    /// </summary>
    /// <typeparam name="T">返回类型</typeparam>
    /// <param name="operation">操作委托</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>操作结果</returns>
    Task<T> ExecuteInTransactionAsync<T>(Func<Task<T>> operation, CancellationToken cancellationToken = default);

    #endregion
}
